from dataclasses import dataclass
from ..config.config import ConfigManager

@dataclass
class RiskParams:
    """风险管理参数配置"""
    max_portfolio_risk: float = 0.02  # 组合最大风险敞口比例
    per_trade_risk: float = 0.01  # 单笔交易风险比例
    max_sell_ratio: float = 0.3   # 风险控制允许的最大卖出量
    max_position_ratio: float = 0.2  # 单个标的持仓上限比例
    min_position_ratio: float = 0.1  # 单个标的持仓下限比例
    max_portfolio_exposure: float = 1.0 # 持仓组合总风险敞口上限
    stop_loss_pct: float = 0.05  # 止损幅度百分比
    take_profit_pct: float = 0.15  # 止盈幅度百分比
    volatility_window: int = 20  # 波动率计算窗口
    min_trade_unit: int = 100  # 最小交易单位
    max_leverage: float = 2.0  # 最大杠杆倍数

class RiskManager:
    """统一风险管理模块"""
    
    def __init__(self, config: ConfigManager):
        """
        :param portfolio_manager: 持仓管理器实例
        :param risk_params: 风险参数配置
        :param volatility_calculator: 波动率计算函数接口
        """
        self._config = config
        self.params = RiskParams(
            per_trade_risk=self._config.get('risk.per_trade_risk'),
            max_position_ratio=self._config.get('risk.max_position_ratio'),
            min_position_ratio=self._config.get('risk.min_position_ratio'),
            max_portfolio_exposure=self._config.get('risk.max_portfolio_exposure'),
            max_sell_ratio=self._config.get('risk.max_sell_ratio')
        )
    
        #self.volatility_calc = volatility_calculator or self.default_volatility

    def bind(self, engine):
        self.engine = engine
        
    # def default_volatility(self, symbol: str, window: int) -> float:
    #     """默认波动率计算（ATR法）"""
    #     if symbol not in self.pm.hist_data:
    #         return 0.0
            
    #     data = self.pm.hist_data[symbol]
    #     if len(data) < window:
    #         return 0.0
            
    #     high_low = data['high'] - data['low']
    #     high_close = (data['high'] - data['close'].shift()).abs()
    #     low_close = (data['low'] - data['close'].shift()).abs()
    #     tr = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)
    #     return tr.rolling(window).mean().iloc[-1]
        
    # def calculate_position_size(
    #     self,
    #     symbol: str,
    #     price: float,
    #     direction: OrderDirection
    # ) -> int:
    #     """综合风险计算头寸规模"""
    #     # 基础头寸计算
    #     base_size = self._base_position_size(price)
        
    #     # 波动率调整
    #     volatility_adj = self._volatility_adjustment(symbol, price)
        
    #     # 集中度限制
    #     concentration_adj = self._concentration_limit(symbol, price)
        
    #     # 杠杆限制
    #     leverage_adj = self._leverage_constraint(base_size * price)
        
    #     # 综合计算最终头寸
    #     final_size = min(
    #         base_size,
    #         volatility_adj,
    #         concentration_adj,
    #         leverage_adj
    #     )
        
    #     # 确保最小交易单位
    #     return max(
    #         self._round_lot(final_size),
    #         self.params.min_trade_unit
    #     )
    
    # def _base_position_size(self, price: float) -> int:
    #     """基础头寸（基于可用资金和风险比例）"""
    #     risk_capital = self.pm.total_equity * self.params.per_trade_risk
    #     return int(risk_capital // price)
    
    # def _volatility_adjustment(self, symbol: str, price: float) -> int:
    #     """波动率调整系数"""
    #     atr = self.volatility_calc(symbol, self.params.volatility_window)
    #     if atr == 0:
    #         return float('inf')
            
    #     max_risk_units = (self.params.per_trade_risk * self.pm.total_equity) / atr
    #     return int(max_risk_units // price)
    
    # def _concentration_limit(self, symbol: str, price: float) -> int:
    #     """集中度限制"""
    #     current_value = self.pm.get_position(symbol).market_value
    #     max_additional = (
    #         self.params.max_position_ratio * self.pm.total_equity - current_value
    #     )
    #     return int(max_additional // price)
    
    # def _leverage_constraint(self, required_cash: float) -> int:
    #     """杠杆限制"""
    #     available_with_leverage = (
    #         self.pm.available_cash * self.params.max_leverage
    #     )
    #     return int(available_with_leverage // required_cash)
    
    # def _round_lot(self, size: int) -> int:
    #     """整手数处理（A股标准）"""
    #     return (size // 100) * 100
    
    # def generate_stop_levels(
    #     self,
    #     symbol: str,
    #     entry_price: float,
    #     direction: OrderDirection
    # ) -> Dict[str, float]:
    #     """生成动态止损止盈价位"""
    #     atr = self.volatility_calc(symbol, self.params.volatility_window)
    #     if direction == OrderDirection.BUY:
    #         stop_loss = entry_price * (1 - self.params.stop_loss_pct)
    #         take_profit = entry_price * (1 + self.params.take_profit_pct)
    #         # 波动率调整
    #         trailing_stop = entry_price - 2 * atr
    #     else:
    #         stop_loss = entry_price * (1 + self.params.stop_loss_pct)
    #         take_profit = entry_price * (1 - self.params.take_profit_pct)
    #         trailing_stop = entry_price + 2 * atr
            
    #     return {
    #         'stop_loss': stop_loss,
    #         'take_profit': take_profit,
    #         'trailing_stop': trailing_stop
    #     }
    
    # def check_portfolio_risk(self) -> bool:
    #     """整体组合风险检查"""
    #     total_risk = sum(
    #         p.market_value / self.pm.total_equity 
    #         for p in self.pm.positions.values()
    #     )
        
    #     return total_risk <= self.params.max_portfolio_risk